/*

   MCL STRING - A component library of the Sigh misc. C library.

   Copyright (c) 2011, Sulaiman A. Mustafa

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   
   ________________________________________________________________________
   
   Note:
      The functions contained herein are documented mcl_str.h 
      
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mcl/str.h"


extern int mcl_str_errno;

int mcl_str_mprobe(mcl_str_match_t* m, int o, int i){
   switch (o){
      case MCL_STR_MCOUNT:
         return m->count;
      case MCL_STR_MLENGTH:
         return (i<m->count?(m->selections)[i].length:-1);
      case MCL_STR_MSTART:
         return (i<m->count?(m->selections)[i].start:-1);
      default:
         return -1;
   }
}

mcl_str_match_t*    mcl_str_match_c(const char *str, const char *pat){
   mcl_str_match_t *matches;
   mcl_str_selection_t *list = NULL;
   int list_size=0, i;
   int len=strlen(pat);
   
   if(!(matches=(mcl_str_match_t *)malloc(sizeof(mcl_str_match_t)))){
      fprintf( stderr, "mcl string matcher: ENOMEM (memory allocation error)\n");
      return NULL;
   }
   matches->count=0;
   
   for (i=0;str[i];++i){
      if (str[i]==*pat && !strncmp(str+i, pat, len)){
         ++list_size;
        	if(!(list=(mcl_str_selection_t *)realloc(list, sizeof(mcl_str_selection_t)*list_size))){
            fprintf( stderr, "mcl string matcher: ENOMEM (memory allocation error)\n");
            free (matches);
            return NULL;
         }
         list[list_size-1].start=i;
         list[list_size-1].length=len;
         ++matches->count;
      }
   }
   matches->selections=list;
   return matches;
}

mcl_str_match_t*    mcl_str_match_free(mcl_str_match_t* p){
   if(p){
      free(p->selections);
      free(p);
   }
   return NULL;
}

mcl_str_t* mcl_str_replace_z(mcl_str_t* str, const char *which, mcl_str_t* what){
   int i, d; 
   d=0; /*  d is used to track the disposition caused by inserting strings 
            longer or shorter then the string they are replacing */ 
   
   mcl_str_match_t* m = mcl_str_match_c(str, which);
   
                                                                                /*printf(
                                                                                       "\n\n"
                                                                                       "%-20s%-20s%-20s%-20s\n"
                                                                                       "----------------------------------------" 
                                                                                       "---------------------------------------\n",
                                                                                       "str", "what", "start", "length"); */
   for (i=0;i<m->count; ++i){
      
      /*printf("%-20s%-20s%-20d%-20d\n", str, what, (m->selections)[i].start+d, (m->selections)[i].length);
      printf("d=%d\nmcl_str_len(what)=%d\n(m->selections)[i].length=%d\n\n", d, mcl_str_len(what), (m->selections)[i].length);*/
      str=mcl_str_insert_z(str, what, (m->selections)[i].start+d, (m->selections)[i].length);
      d+=mcl_str_len(what)-(m->selections)[i].length;
   }
   mcl_str_match_free(m);
   return str;
}



